﻿#ifndef __AVOID_CONTROL_SINGLE_EDIT_HEAD_FILE_INCLUDED__
#define __AVOID_CONTROL_SINGLE_EDIT_HEAD_FILE_INCLUDED__
#include "control.h"
#include "interface/IFont.h"
#include "interface/IBackground.h"
#include <vector>

namespace swui
{
#pragma warning(push)
#pragma warning(disable:4250)
	class ctlSingleEdit : virtual public ctlRoot,
		public IFont, public IBackground
	{
	public:
		static const ctlControlType uniqueType = ctlControlType::ctlSingleEdit;
	public:
		virtual ~ctlSingleEdit() { destroy(); }
		bool create(ctlRoot* parent, ctlPoint pos, unsigned width, 
			const ctlText& lpszText = ctlText(L""),
			const ctlStyleEdit& = ctlStyleEdit(ctlStyleEdit::common));
	public:
		//获取被选中的字符串
		std::string getSelectedString();
		std::wstring getSelectedWideString();
		//获取选中字符串的位置
		std::pair<unsigned, unsigned> getSelected();
		//设置选中的字符串
		bool setSelected(std::pair<unsigned, unsigned>);
		//获得内边距
		unsigned getRightPadding();
		unsigned getLeftPadding();
		unsigned getHeightPadding();
		//获取插入符位置（若焦点不在当前控件返回 0xffffffff）
		unsigned getCaretPosition();
		//设置插入符位置
		bool setCaretPosition(unsigned pos);
		//设置插入付到末尾
		bool setCaretAppend();
	public:
		void setAccess(ctlAccess access);
		ctlAccess getAccess();
		bool accessWrite();
		bool accessRead();
	public:
		virtual bool setText(const ctlText& lpszText);
	protected:
		virtual void _redraw_(_ctlInterior::drawInfo*);
		virtual void _mouse_event_(ctlMouseEvent*);
		virtual void _key_event_(ctlKeyEvent*);
		virtual void _position_event_(ctlPositionEvent*);
	protected:
		typedef unsigned _exactPos;
		_exactPos _edit_caret_pos_begin, _edit_caret_pos_end;
	private:
		std::vector<int> _edit_str;
		unsigned _edit_left_pos;	
		unsigned _edit_left_offset;
		ctlAccess _edit_access;
	private:
		struct {
			_ctlInterior::textpack pack;
			bool enable;
			_exactPos begin, end;
		} _edit_back_insert, _edit_back_remove;
	protected:
		virtual _exactPos _insert_text(_exactPos pos, const _ctlInterior::textpack& text);
		virtual void _remove_selected();
	private:
		_exactPos _edit_map_point_to_pos(ctlPoint);
		ctlPoint _edit_map_pos_to_point(_exactPos);
		void _flush_caret();
		virtual void _flush_font_();
		void _check_scroll();
		void _send_change_event();
		bool _send_edit_event(std::wstring& str, decltype(ctlNotifyEdit::copy));
	};
#pragma warning(pop)
	inline void ctlSingleEdit::setAccess(ctlAccess access) {
		_edit_access = access;
		if(access == ctlAccess::read || access == ctlAccess::none)
			_edit_caret_pos_end = _edit_caret_pos_begin;
		_flush_caret();
	}
	inline ctlAccess ctlSingleEdit::getAccess() {
		return _edit_access;
	}
	inline bool ctlSingleEdit::accessWrite() {
		return enumTypeAnd(getAccess(), ctlAccess::write) != ctlAccess::none;
	}
	inline bool ctlSingleEdit::accessRead() {
		return enumTypeAnd(getAccess(), ctlAccess::read) != ctlAccess::none;
	}
	inline unsigned ctlSingleEdit::getLeftPadding() {
		return 3;
	}
	inline unsigned ctlSingleEdit::getRightPadding() {
		return 3;
	}
	inline unsigned ctlSingleEdit::getHeightPadding() {
		return 3;
	}
}

#endif